case CMSG_MEM_REQUEST_SET:
{
mem_request_t *req = (mem_request_t *)&msg->msg[0];
- if ( msg->length != sizeof(mem_request_t) )
- goto parse_error;
set_new_target(req->target);
req->status = 0;
}
break;
+
default:
- goto parse_error;
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- msg->length = 0;
- ctrl_if_send_response(msg);
}
static int balloon_write(struct file *file, const char __user *buffer,
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
static kmem_cache_t *buffer_head_cachep;
+#else
+static request_queue_t *plugged_queue;
+void bdev_put(struct block_device *bdev)
+{
+ request_queue_t *q = plugged_queue;
+ /* We might be giving up last reference to plugged queue. Flush if so. */
+ if ( (q != NULL) &&
+ (q == bdev_get_queue(bdev)) &&
+ (cmpxchg(&plugged_queue, q, NULL) == q) )
+ blk_run_queue(q);
+ /* It's now safe to drop the block device. */
+ blkdev_put(bdev);
+}
#endif
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
blkif_put(blkif);
}
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
/* Push the batch through to disc. */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
run_task_queue(&tq_disk);
+#else
+ if ( plugged_queue != NULL )
+ {
+ blk_run_queue(plugged_queue);
+ plugged_queue = NULL;
+ }
#endif
}
}
for ( i = 0; i < nr_psegs; i++ )
{
struct bio *bio;
+ request_queue_t *q;
bio = bio_alloc(GFP_ATOMIC, 1);
if ( unlikely(bio == NULL) )
phys_seg[i].nr_sects << 9,
phys_seg[i].buffer & ~PAGE_MASK);
- submit_bio(operation | (1 << BIO_RW_SYNC), bio);
+ if ( (q = bdev_get_queue(bio->bi_bdev)) != plugged_queue )
+ {
+ if ( plugged_queue != NULL )
+ blk_run_queue(plugged_queue);
+ plugged_queue = q;
+ }
+
+ submit_bio(operation, bio);
}
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
typedef struct rb_root rb_root_t;
typedef struct rb_node rb_node_t;
+extern void bdev_put(struct block_device *bdev);
#else
struct block_device;
+#define bdev_put(_b) ((void)0)
#endif
typedef struct blkif_st {
blkif_disconnect_complete(_b); \
} while (0)
-/* An entry in a list of xen_extents. */
-typedef struct _blkif_extent_le {
- blkif_extent_t extent; /* an individual extent */
- struct _blkif_extent_le *next; /* and a pointer to the next */
- struct block_device *bdev;
-} blkif_extent_le_t;
-
typedef struct _vbd {
- blkif_vdev_t vdevice; /* what the domain refers to this vbd as */
- unsigned char readonly; /* Non-zero -> read-only */
- unsigned char type; /* VDISK_TYPE_xxx */
- blkif_extent_le_t *extents; /* list of xen_extents making up this vbd */
- rb_node_t rb; /* for linking into R-B tree lookup struct */
+ blkif_vdev_t vdevice; /* what the domain refers to this vbd as */
+ unsigned char readonly; /* Non-zero -> read-only */
+ unsigned char type; /* VDISK_TYPE_xxx */
+ blkif_pdev_t pdevice; /* phys device that this vbd maps to */
+ struct block_device *bdev;
+ rb_node_t rb; /* for linking into R-B tree lookup struct */
} vbd_t;
void vbd_create(blkif_be_vbd_create_t *create);
-void vbd_grow(blkif_be_vbd_grow_t *grow);
-void vbd_shrink(blkif_be_vbd_shrink_t *shrink);
void vbd_destroy(blkif_be_vbd_destroy_t *delete);
int vbd_probe(blkif_t *blkif, vdisk_t *vbd_info, int max_vbds);
void destroy_all_vbds(blkif_t *blkif);
switch ( msg->subtype )
{
case CMSG_BLKIF_BE_CREATE:
- if ( msg->length != sizeof(blkif_be_create_t) )
- goto parse_error;
blkif_create((blkif_be_create_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_DESTROY:
- if ( msg->length != sizeof(blkif_be_destroy_t) )
- goto parse_error;
blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_CONNECT:
- if ( msg->length != sizeof(blkif_be_connect_t) )
- goto parse_error;
blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_DISCONNECT:
- if ( msg->length != sizeof(blkif_be_disconnect_t) )
- goto parse_error;
if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
return; /* Sending the response is deferred until later. */
break;
case CMSG_BLKIF_BE_VBD_CREATE:
- if ( msg->length != sizeof(blkif_be_vbd_create_t) )
- goto parse_error;
vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_VBD_DESTROY:
- if ( msg->length != sizeof(blkif_be_vbd_destroy_t) )
- goto parse_error;
vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
break;
- case CMSG_BLKIF_BE_VBD_GROW:
- if ( msg->length != sizeof(blkif_be_vbd_grow_t) )
- goto parse_error;
- vbd_grow((blkif_be_vbd_grow_t *)&msg->msg[0]);
- break;
- case CMSG_BLKIF_BE_VBD_SHRINK:
- if ( msg->length != sizeof(blkif_be_vbd_shrink_t) )
- goto parse_error;
- vbd_shrink((blkif_be_vbd_shrink_t *)&msg->msg[0]);
- break;
default:
- goto parse_error;
+ DPRINTK("Parse error while reading message subtype %d, len %d\n",
+ msg->subtype, msg->length);
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- DPRINTK("Parse error while reading message subtype %d, len %d\n",
- msg->subtype, msg->length);
- msg->length = 0;
- ctrl_if_send_response(msg);
}
void blkif_ctrlif_init(void)
* in vbd_translate. All other lookups are implicitly protected because the
* only caller (the control message dispatch routine) serializes the calls.
*
- * Copyright (c) 2003-2004, Keir Fraser & Steve Hand
+ * Copyright (c) 2003-2005, Keir Fraser & Steve Hand
*/
#include "common.h"
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-static dev_t vbd_map_devnum(blkif_pdev_t);
+static inline dev_t vbd_map_devnum(blkif_pdev_t cookie)
+{ return MKDEV(cookie>>8, cookie&0xff); }
+#define vbd_sz(_v) ((_v)->bdev->bd_part ? \
+ (_v)->bdev->bd_part->nr_sects : (_v)->bdev->bd_disk->capacity)
+#else
+#define vbd_sz(_v) (blk_size[MAJOR((_v)->pdevice)][MINOR((_v)->pdevice)]*2)
#endif
void vbd_create(blkif_be_vbd_create_t *create)
vbd->vdevice = vdevice;
vbd->readonly = create->readonly;
vbd->type = VDISK_TYPE_DISK | VDISK_FLAG_VIRT;
- vbd->extents = NULL;
-
- spin_lock(&blkif->vbd_lock);
- rb_link_node(&vbd->rb, rb_parent, rb_p);
- rb_insert_color(&vbd->rb, &blkif->vbd_rb);
- spin_unlock(&blkif->vbd_lock);
-
- DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
- vdevice, create->domid);
- create->status = BLKIF_BE_STATUS_OKAY;
-}
-
-
-/* Grow a VBD by appending a new extent. Fails if the VBD doesn't exist. */
-void vbd_grow(blkif_be_vbd_grow_t *grow)
-{
- blkif_t *blkif;
- blkif_extent_le_t **px, *x;
- vbd_t *vbd = NULL;
- rb_node_t *rb;
- blkif_vdev_t vdevice = grow->vdevice;
- unsigned long sz;
-
- blkif = blkif_find_by_handle(grow->domid, grow->blkif_handle);
- if ( unlikely(blkif == NULL) )
- {
- DPRINTK("vbd_grow attempted for non-existent blkif (%u,%u)\n",
- grow->domid, grow->blkif_handle);
- grow->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
- return;
- }
-
- rb = blkif->vbd_rb.rb_node;
- while ( rb != NULL )
- {
- vbd = rb_entry(rb, vbd_t, rb);
- if ( vdevice < vbd->vdevice )
- rb = rb->rb_left;
- else if ( vdevice > vbd->vdevice )
- rb = rb->rb_right;
- else
- break;
- }
-
- if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
- {
- DPRINTK("vbd_grow: attempted to append extent to non-existent VBD.\n");
- grow->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
- return;
- }
-
- if ( grow->extent.sector_start > 0 )
- {
- DPRINTK("vbd_grow: dev %08x start not zero.\n", grow->extent.device);
- grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
- return;
- }
-
- if ( unlikely((x = kmalloc(sizeof(blkif_extent_le_t),
- GFP_KERNEL)) == NULL) )
- {
- DPRINTK("vbd_grow: out of memory\n");
- grow->status = BLKIF_BE_STATUS_OUT_OF_MEMORY;
- return;
- }
/* Mask to 16-bit for compatibility with old tools */
- x->extent.device = grow->extent.device & 0xffff;
- x->extent.sector_start = grow->extent.sector_start;
- x->extent.sector_length = grow->extent.sector_length;
- x->next = (blkif_extent_le_t *)NULL;
+ vbd->pdevice = create->pdevice & 0xffff;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- x->bdev = open_by_devnum(vbd_map_devnum(x->extent.device),
- vbd->readonly ? FMODE_READ : FMODE_WRITE);
- if ( IS_ERR(x->bdev) )
- {
- DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
- grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
- goto out;
- }
- /* XXXcl maybe bd_claim? */
-
- if ( (x->bdev->bd_disk == NULL) )
- {
- DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
- grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
- blkdev_put(x->bdev);
- goto out;
- }
-
- /* get size in sectors */
- if ( x->bdev->bd_part )
- sz = x->bdev->bd_part->nr_sects;
- else
- sz = x->bdev->bd_disk->capacity;
-
-#else
- if( !blk_size[MAJOR(x->extent.device)] )
- {
- DPRINTK("vbd_grow: device %08x doesn't exist.\n", x->extent.device);
- grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
- goto out;
- }
-
- /* convert blocks (1KB) to sectors */
- sz = blk_size[MAJOR(x->extent.device)][MINOR(x->extent.device)] * 2;
-
- if ( sz == 0 )
+ vbd->bdev = open_by_devnum(
+ vbd_map_devnum(vbd->pdevice),
+ vbd->readonly ? FMODE_READ : FMODE_WRITE);
+ if ( IS_ERR(vbd->bdev) )
{
- DPRINTK("vbd_grow: device %08x zero size!\n", x->extent.device);
- grow->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
- goto out;
- }
-#endif
-
- /*
- * NB. This test assumes sector_start == 0, which is always the case
- * in Xen 1.3. In fact the whole grow/shrink interface could do with
- * some simplification.
- */
- if ( x->extent.sector_length > sz )
- x->extent.sector_length = sz;
-
- DPRINTK("vbd_grow: requested_len %llu actual_len %lu\n",
- x->extent.sector_length, sz);
-
- for ( px = &vbd->extents; *px != NULL; px = &(*px)->next )
- continue;
-
- *px = x; /* ATOMIC: no need for vbd_lock. */
-
- DPRINTK("Successful grow of vdev=%04x (dom=%u)\n",
- vdevice, grow->domid);
-
- grow->status = BLKIF_BE_STATUS_OKAY;
- return;
-
- out:
- kfree(x);
-}
-
-
-void vbd_shrink(blkif_be_vbd_shrink_t *shrink)
-{
- blkif_t *blkif;
- blkif_extent_le_t **px, *x;
- vbd_t *vbd = NULL;
- rb_node_t *rb;
- blkif_vdev_t vdevice = shrink->vdevice;
-
- blkif = blkif_find_by_handle(shrink->domid, shrink->blkif_handle);
- if ( unlikely(blkif == NULL) )
- {
- DPRINTK("vbd_shrink attempted for non-existent blkif (%u,%u)\n",
- shrink->domid, shrink->blkif_handle);
- shrink->status = BLKIF_BE_STATUS_INTERFACE_NOT_FOUND;
+ DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+ create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
return;
}
- rb = blkif->vbd_rb.rb_node;
- while ( rb != NULL )
- {
- vbd = rb_entry(rb, vbd_t, rb);
- if ( vdevice < vbd->vdevice )
- rb = rb->rb_left;
- else if ( vdevice > vbd->vdevice )
- rb = rb->rb_right;
- else
- break;
- }
-
- if ( unlikely(vbd == NULL) || unlikely(vbd->vdevice != vdevice) )
+ if ( (vbd->bdev->bd_disk == NULL) )
{
- shrink->status = BLKIF_BE_STATUS_VBD_NOT_FOUND;
+ DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+ create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
+ bdev_put(vbd->bdev);
return;
}
-
- if ( unlikely(vbd->extents == NULL) )
+#else
+ if ( (blk_size[MAJOR(vbd->pdevice)] == NULL) || (vbd_sz(vbd) == 0) )
{
- shrink->status = BLKIF_BE_STATUS_EXTENT_NOT_FOUND;
+ DPRINTK("vbd_creat: device %08x doesn't exist.\n", vbd->pdevice);
+ create->status = BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND;
return;
}
-
- /* Find the last extent. We now know that there is at least one. */
- for ( px = &vbd->extents; (*px)->next != NULL; px = &(*px)->next )
- continue;
-
- x = *px;
- *px = x->next; /* ATOMIC: no need for vbd_lock. */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- blkdev_put(x->bdev);
#endif
- kfree(x);
- shrink->status = BLKIF_BE_STATUS_OKAY;
+ spin_lock(&blkif->vbd_lock);
+ rb_link_node(&vbd->rb, rb_parent, rb_p);
+ rb_insert_color(&vbd->rb, &blkif->vbd_rb);
+ spin_unlock(&blkif->vbd_lock);
+
+ DPRINTK("Successful creation of vdev=%04x (dom=%u)\n",
+ vdevice, create->domid);
+ create->status = BLKIF_BE_STATUS_OKAY;
}
blkif_t *blkif;
vbd_t *vbd;
rb_node_t *rb;
- blkif_extent_le_t *x, *t;
blkif_vdev_t vdevice = destroy->vdevice;
blkif = blkif_find_by_handle(destroy->domid, destroy->blkif_handle);
spin_lock(&blkif->vbd_lock);
rb_erase(rb, &blkif->vbd_rb);
spin_unlock(&blkif->vbd_lock);
-
- x = vbd->extents;
+ bdev_put(vbd->bdev);
kfree(vbd);
-
- while ( x != NULL )
- {
- t = x->next;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- blkdev_put(x->bdev);
-#endif
- kfree(x);
- x = t;
- }
}
{
vbd_t *vbd;
rb_node_t *rb;
- blkif_extent_le_t *x, *t;
spin_lock(&blkif->vbd_lock);
while ( (rb = blkif->vbd_rb.rb_node) != NULL )
{
vbd = rb_entry(rb, vbd_t, rb);
-
rb_erase(rb, &blkif->vbd_rb);
- x = vbd->extents;
+ spin_unlock(&blkif->vbd_lock);
+ bdev_put(vbd->bdev);
kfree(vbd);
-
- while ( x != NULL )
- {
- t = x->next;
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- blkdev_put(x->bdev);
-#endif
- kfree(x);
- x = t;
- }
+ spin_lock(&blkif->vbd_lock);
}
spin_unlock(&blkif->vbd_lock);
}
-static int vbd_probe_single(blkif_t *blkif, vdisk_t *vbd_info, vbd_t *vbd)
+static void vbd_probe_single(blkif_t *blkif, vdisk_t *vbd_info, vbd_t *vbd)
{
- blkif_extent_le_t *x;
-
- vbd_info->device = vbd->vdevice;
- vbd_info->info = vbd->type;
- if ( vbd->readonly )
- vbd_info->info |= VDISK_FLAG_RO;
- vbd_info->capacity = 0ULL;
- for ( x = vbd->extents; x != NULL; x = x->next )
- vbd_info->capacity += x->extent.sector_length;
-
- return 0;
+ vbd_info->device = vbd->vdevice;
+ vbd_info->info = vbd->type | (vbd->readonly ? VDISK_FLAG_RO : 0);
+ vbd_info->capacity = vbd_sz(vbd);
}
for ( ; ; )
{
/* STEP 2. Dealt with left subtree. Now process current node. */
- if ( (rc = vbd_probe_single(blkif, &vbd_info[nr_vbds],
- rb_entry(rb, vbd_t, rb))) != 0 )
- goto out;
+ vbd_probe_single(blkif, &vbd_info[nr_vbds], rb_entry(rb, vbd_t, rb));
if ( ++nr_vbds == max_vbds )
goto out;
int vbd_translate(phys_seg_t *pseg, blkif_t *blkif, int operation)
{
- blkif_extent_le_t *x;
- vbd_t *vbd;
- rb_node_t *rb;
- blkif_sector_t sec_off;
- unsigned long nr_secs;
+ vbd_t *vbd;
+ rb_node_t *rb;
+ int rc = -EACCES;
/* Take the vbd_lock because another thread could be updating the tree. */
spin_lock(&blkif->vbd_lock);
DPRINTK("vbd_translate; domain %u attempted to access "
"non-existent VBD.\n", blkif->domid);
-
- spin_unlock(&blkif->vbd_lock);
- return -ENODEV;
+ rc = -ENODEV;
+ goto out;
found:
if ( (operation == WRITE) && vbd->readonly )
- {
- spin_unlock(&blkif->vbd_lock);
- return -EACCES;
- }
+ goto out;
- /*
- * Now iterate through the list of blkif_extents, working out which should
- * be used to perform the translation.
- */
- sec_off = pseg->sector_number;
- nr_secs = pseg->nr_sects;
- for ( x = vbd->extents; x != NULL; x = x->next )
- {
- if ( sec_off < x->extent.sector_length )
- {
- pseg->dev = x->extent.device;
- pseg->bdev = x->bdev;
- pseg->sector_number = x->extent.sector_start + sec_off;
- if ( unlikely((sec_off + nr_secs) > x->extent.sector_length) )
- goto overrun;
- spin_unlock(&blkif->vbd_lock);
- return 1;
- }
- sec_off -= x->extent.sector_length;
- }
+ if ( unlikely((pseg->sector_number + pseg->nr_sects) > vbd_sz(vbd)) )
+ goto out;
- DPRINTK("vbd_translate: end of vbd.\n");
- spin_unlock(&blkif->vbd_lock);
- return -EACCES;
-
- /*
- * Here we deal with overrun onto the following extent. We don't deal with
- * overrun of more than one boundary since each request is restricted to
- * 2^9 512-byte sectors, so it should be trivial for control software to
- * ensure that extents are large enough to prevent excessive overrun.
- */
- overrun:
-
- /* Adjust length of first chunk to run to end of first extent. */
- pseg[0].nr_sects = x->extent.sector_length - sec_off;
-
- /* Set second chunk buffer and length to start where first chunk ended. */
- pseg[1].buffer = pseg[0].buffer + (pseg[0].nr_sects << 9);
- pseg[1].nr_sects = nr_secs - pseg[0].nr_sects;
-
- /* Now move to the next extent. Check it exists and is long enough! */
- if ( unlikely((x = x->next) == NULL) ||
- unlikely(x->extent.sector_length < pseg[1].nr_sects) )
- {
- DPRINTK("vbd_translate: multiple overruns or end of vbd.\n");
- spin_unlock(&blkif->vbd_lock);
- return -EACCES;
- }
+ pseg->dev = vbd->pdevice;
+ pseg->bdev = vbd->bdev;
+ rc = 1;
- /* Store the real device and start sector for the second chunk. */
- pseg[1].dev = x->extent.device;
- pseg[1].bdev = x->bdev;
- pseg[1].sector_number = x->extent.sector_start;
-
+ out:
spin_unlock(&blkif->vbd_lock);
- return 2;
+ return rc;
}
-
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
-
-#define MAJOR_XEN(dev) ((dev)>>8)
-#define MINOR_XEN(dev) ((dev) & 0xff)
-
-#ifndef FANCY_REMAPPING
-static dev_t vbd_map_devnum(blkif_pdev_t cookie)
-{
- int major = MAJOR_XEN(cookie);
- int minor = MINOR_XEN(cookie);
-
- return MKDEV(major, minor);
-}
-#else
-#define XEN_IDE0_MAJOR IDE0_MAJOR
-#define XEN_IDE1_MAJOR IDE1_MAJOR
-#define XEN_IDE2_MAJOR IDE2_MAJOR
-#define XEN_IDE3_MAJOR IDE3_MAJOR
-#define XEN_IDE4_MAJOR IDE4_MAJOR
-#define XEN_IDE5_MAJOR IDE5_MAJOR
-#define XEN_IDE6_MAJOR IDE6_MAJOR
-#define XEN_IDE7_MAJOR IDE7_MAJOR
-#define XEN_IDE8_MAJOR IDE8_MAJOR
-#define XEN_IDE9_MAJOR IDE9_MAJOR
-#define XEN_SCSI_DISK0_MAJOR SCSI_DISK0_MAJOR
-#define XEN_SCSI_DISK1_MAJOR SCSI_DISK1_MAJOR
-#define XEN_SCSI_DISK2_MAJOR SCSI_DISK2_MAJOR
-#define XEN_SCSI_DISK3_MAJOR SCSI_DISK3_MAJOR
-#define XEN_SCSI_DISK4_MAJOR SCSI_DISK4_MAJOR
-#define XEN_SCSI_DISK5_MAJOR SCSI_DISK5_MAJOR
-#define XEN_SCSI_DISK6_MAJOR SCSI_DISK6_MAJOR
-#define XEN_SCSI_DISK7_MAJOR SCSI_DISK7_MAJOR
-#define XEN_SCSI_CDROM_MAJOR SCSI_CDROM_MAJOR
-
-static dev_t vbd_map_devnum(blkif_pdev_t cookie)
-{
- int new_major;
- int major = MAJOR_XEN(cookie);
- int minor = MINOR_XEN(cookie);
-
- switch (major) {
- case XEN_IDE0_MAJOR: new_major = IDE0_MAJOR; break;
- case XEN_IDE1_MAJOR: new_major = IDE1_MAJOR; break;
- case XEN_IDE2_MAJOR: new_major = IDE2_MAJOR; break;
- case XEN_IDE3_MAJOR: new_major = IDE3_MAJOR; break;
- case XEN_IDE4_MAJOR: new_major = IDE4_MAJOR; break;
- case XEN_IDE5_MAJOR: new_major = IDE5_MAJOR; break;
- case XEN_IDE6_MAJOR: new_major = IDE6_MAJOR; break;
- case XEN_IDE7_MAJOR: new_major = IDE7_MAJOR; break;
- case XEN_IDE8_MAJOR: new_major = IDE8_MAJOR; break;
- case XEN_IDE9_MAJOR: new_major = IDE9_MAJOR; break;
- case XEN_SCSI_DISK0_MAJOR: new_major = SCSI_DISK0_MAJOR; break;
- case XEN_SCSI_DISK1_MAJOR ... XEN_SCSI_DISK7_MAJOR:
- new_major = SCSI_DISK1_MAJOR + major - XEN_SCSI_DISK1_MAJOR;
- break;
- case XEN_SCSI_CDROM_MAJOR: new_major = SCSI_CDROM_MAJOR; break;
- default: new_major = 0; break;
- }
-
- return MKDEV(new_major, minor);
-}
-#endif
-
-#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION_CODE(2,6,0) */
switch ( msg->subtype )
{
case CMSG_BLKIF_FE_INTERFACE_STATUS:
- if ( msg->length != sizeof(blkif_fe_interface_status_t) )
- goto parse_error;
blkif_status((blkif_fe_interface_status_t *)
&msg->msg[0]);
- break;
+ break;
default:
- goto parse_error;
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- msg->length = 0;
- ctrl_if_send_response(msg);
}
int wait_for_blkif(void)
switch ( msg->subtype )
{
case CMSG_BLKIF_FE_INTERFACE_STATUS:
- if ( msg->length != sizeof(blkif_fe_interface_status_t) )
- goto parse_error;
blkif_ptbe_status((blkif_fe_interface_status_t *) &msg->msg[0]);
- break;
+ break;
default:
goto parse_error;
}
+ break;
+
case CMSG_BLKIF_BE:
/* send a copy of the message to user if wanted */
switch ( msg->subtype )
{
case CMSG_BLKIF_BE_CREATE:
- if ( msg->length != sizeof(blkif_be_create_t) )
- goto parse_error;
blkif_ptfe_create((blkif_be_create_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_DESTROY:
- if ( msg->length != sizeof(blkif_be_destroy_t) )
- goto parse_error;
blkif_ptfe_destroy((blkif_be_destroy_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_CONNECT:
- if ( msg->length != sizeof(blkif_be_connect_t) )
- goto parse_error;
blkif_ptfe_connect((blkif_be_connect_t *)&msg->msg[0]);
break;
case CMSG_BLKIF_BE_DISCONNECT:
- if ( msg->length != sizeof(blkif_be_disconnect_t) )
- goto parse_error;
if ( !blkif_ptfe_disconnect((blkif_be_disconnect_t *)&msg->msg[0],
msg->id) )
return;
((blkif_be_vbd_destroy_t *)&msg->msg[0])->status
= BLKIF_BE_STATUS_OKAY;
break;
- case CMSG_BLKIF_BE_VBD_GROW:
- DPRINTK("PT got VBD_GROW\n");
- ((blkif_be_vbd_grow_t *)&msg->msg[0])->status
- = BLKIF_BE_STATUS_OKAY;
- break;
- case CMSG_BLKIF_BE_VBD_SHRINK:
- DPRINTK("PT got VBD_SHRINK\n");
- ((blkif_be_vbd_shrink_t *)&msg->msg[0])->status
- = BLKIF_BE_STATUS_OKAY;
- break;
default:
goto parse_error;
}
+
+ break;
}
ctrl_if_send_response(msg);
switch ( msg->subtype )
{
case CMSG_NETIF_BE_CREATE:
- if ( msg->length != sizeof(netif_be_create_t) )
- goto parse_error;
netif_create((netif_be_create_t *)&msg->msg[0]);
break;
case CMSG_NETIF_BE_DESTROY:
- if ( msg->length != sizeof(netif_be_destroy_t) )
- goto parse_error;
netif_destroy((netif_be_destroy_t *)&msg->msg[0]);
break;
case CMSG_NETIF_BE_CREDITLIMIT:
- if ( msg->length != sizeof(netif_be_creditlimit_t) )
- goto parse_error;
netif_creditlimit((netif_be_creditlimit_t *)&msg->msg[0]);
break;
case CMSG_NETIF_BE_CONNECT:
- if ( msg->length != sizeof(netif_be_connect_t) )
- goto parse_error;
netif_connect((netif_be_connect_t *)&msg->msg[0]);
break;
case CMSG_NETIF_BE_DISCONNECT:
- if ( msg->length != sizeof(netif_be_disconnect_t) )
- goto parse_error;
if ( !netif_disconnect((netif_be_disconnect_t *)&msg->msg[0],msg->id) )
return; /* Sending the response is deferred until later. */
break;
default:
- goto parse_error;
+ DPRINTK("Parse error while reading message subtype %d, len %d\n",
+ msg->subtype, msg->length);
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- DPRINTK("Parse error while reading message subtype %d, len %d\n",
- msg->subtype, msg->length);
- msg->length = 0;
- ctrl_if_send_response(msg);
}
void netif_ctrlif_init(void)
switch (msg->subtype) {
case CMSG_NETIF_FE_INTERFACE_STATUS:
- if (msg->length != sizeof(netif_fe_interface_status_t))
- goto error;
netif_interface_status((netif_fe_interface_status_t *) &msg->msg[0]);
break;
case CMSG_NETIF_FE_DRIVER_STATUS:
- if (msg->length != sizeof(netif_fe_driver_status_t))
- goto error;
netif_driver_status((netif_fe_driver_status_t *) &msg->msg[0]);
break;
- error:
default:
msg->length = 0;
break;
switch ( msg->subtype )
{
case CMSG_USBIF_BE_CREATE:
- if ( msg->length != sizeof(usbif_be_create_t) )
- goto parse_error;
usbif_create((usbif_be_create_t *)&msg->msg[0]);
break;
case CMSG_USBIF_BE_DESTROY:
- if ( msg->length != sizeof(usbif_be_destroy_t) )
- goto parse_error;
usbif_destroy((usbif_be_destroy_t *)&msg->msg[0]);
break;
case CMSG_USBIF_BE_CONNECT:
- if ( msg->length != sizeof(usbif_be_connect_t) )
- goto parse_error;
usbif_connect((usbif_be_connect_t *)&msg->msg[0]);
break;
case CMSG_USBIF_BE_DISCONNECT:
- if ( msg->length != sizeof(usbif_be_disconnect_t) )
- goto parse_error;
if ( !usbif_disconnect((usbif_be_disconnect_t *)&msg->msg[0],msg->id) )
return; /* Sending the response is deferred until later. */
break;
case CMSG_USBIF_BE_CLAIM_PORT:
- if ( msg->length != sizeof(usbif_be_claim_port_t) )
- goto parse_error;
usbif_claim_port((usbif_be_claim_port_t *)&msg->msg[0]);
break;
case CMSG_USBIF_BE_RELEASE_PORT:
- if ( msg->length != sizeof(usbif_be_release_port_t) )
- goto parse_error;
usbif_release_port((usbif_be_release_port_t *)&msg->msg[0]);
break;
default:
- goto parse_error;
+ DPRINTK("Parse error while reading message subtype %d, len %d\n",
+ msg->subtype, msg->length);
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- DPRINTK("Parse error while reading message subtype %d, len %d\n",
- msg->subtype, msg->length);
- msg->length = 0;
- ctrl_if_send_response(msg);
}
void usbif_ctrlif_init(void)
switch ( msg->subtype )
{
case CMSG_USBIF_FE_INTERFACE_STATUS_CHANGED:
- if ( msg->length != sizeof(usbif_fe_interface_status_changed_t) )
- goto parse_error;
usbif_status_change((usbif_fe_interface_status_changed_t *)
&msg->msg[0]);
- break;
+ break;
/* New interface...? */
default:
- goto parse_error;
+ msg->length = 0;
+ break;
}
ctrl_if_send_response(msg);
- return;
-
- parse_error:
- msg->length = 0;
- ctrl_if_send_response(msg);
}
static void send_driver_up(void)
((blkif_be_vbd_grow_t *)msg->msg)->extent.sector_length,
((blkif_be_vbd_grow_t *)msg->msg)->extent.device);
break;
- case CMSG_BLKIF_BE_VBD_SHRINK:
- if ( msg->length != sizeof(blkif_be_vbd_shrink_t) )
- goto parse_error;
- printf("[CONTROL_MSG] CMSG_BLKIF_BE_VBD_SHRINK(d:%d,h:%d,v:%d)\n",
- ((blkif_be_vbd_shrink_t *)msg->msg)->domid,
- ((blkif_be_vbd_shrink_t *)msg->msg)->blkif_handle,
- ((blkif_be_vbd_shrink_t *)msg->msg)->vdevice);
- break;
default:
goto parse_error;
}
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
C2P(blkif_be_vbd_create_t, domid, Int, Long);
C2P(blkif_be_vbd_create_t, blkif_handle, Int, Long);
+ C2P(blkif_be_vbd_create_t, pdevice, Int, Long);
C2P(blkif_be_vbd_create_t, vdevice, Int, Long);
C2P(blkif_be_vbd_create_t, readonly, Int, Long);
C2P(blkif_be_vbd_create_t, status, Int, Long);
C2P(blkif_be_vbd_destroy_t, vdevice, Int, Long);
C2P(blkif_be_vbd_destroy_t, status, Int, Long);
return dict;
- case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
- C2P(blkif_be_vbd_grow_t, domid, Int, Long);
- C2P(blkif_be_vbd_grow_t, blkif_handle, Int, Long);
- C2P(blkif_be_vbd_grow_t, vdevice, Int, Long);
- C2P(blkif_be_vbd_grow_t, extent.sector_start,
- Long, UnsignedLongLong);
- C2P(blkif_be_vbd_grow_t, extent.sector_length,
- Long, UnsignedLongLong);
- C2P(blkif_be_vbd_grow_t, extent.device, Int, Long);
- C2P(blkif_be_vbd_grow_t, status, Int, Long);
- return dict;
- case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
- C2P(blkif_be_vbd_shrink_t, domid, Int, Long);
- C2P(blkif_be_vbd_shrink_t, blkif_handle, Int, Long);
- C2P(blkif_be_vbd_shrink_t, vdevice, Int, Long);
- C2P(blkif_be_vbd_shrink_t, status, Int, Long);
- return dict;
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_DRIVER_STATUS):
C2P(blkif_be_driver_status_t, status, Int, Long);
return dict;
case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE):
P2C(blkif_be_vbd_create_t, domid, u32);
P2C(blkif_be_vbd_create_t, blkif_handle, u32);
+ P2C(blkif_be_vbd_create_t, pdevice, blkif_pdev_t);
P2C(blkif_be_vbd_create_t, vdevice, blkif_vdev_t);
P2C(blkif_be_vbd_create_t, readonly, u16);
break;
P2C(blkif_be_vbd_destroy_t, blkif_handle, u32);
P2C(blkif_be_vbd_destroy_t, vdevice, blkif_vdev_t);
break;
- case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW):
- P2C(blkif_be_vbd_grow_t, domid, u32);
- P2C(blkif_be_vbd_grow_t, blkif_handle, u32);
- P2C(blkif_be_vbd_grow_t, vdevice, blkif_vdev_t);
- P2C(blkif_be_vbd_grow_t, extent.sector_start, blkif_sector_t);
- P2C(blkif_be_vbd_grow_t, extent.sector_length, blkif_sector_t);
- P2C(blkif_be_vbd_grow_t, extent.device, blkif_pdev_t);
- break;
- case TYPE(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_SHRINK):
- P2C(blkif_be_vbd_shrink_t, domid, u32);
- P2C(blkif_be_vbd_shrink_t, blkif_handle, u32);
- P2C(blkif_be_vbd_shrink_t, vdevice, blkif_vdev_t);
- break;
case TYPE(CMSG_NETIF_FE, CMSG_NETIF_FE_INTERFACE_STATUS):
P2C(netif_fe_interface_status_t, handle, u32);
P2C(netif_fe_interface_status_t, status, u32);
msg = packMsg('blkif_be_vbd_create_t',
{ 'domid' : self.controller.dom,
'blkif_handle' : backend.handle,
+ 'pdevice' : self.device,
'vdevice' : self.vdev,
'readonly' : self.readonly() })
backend.writeRequest(msg, response=d)
return d
def respond_be_vbd_create(self, msg):
- """Response handler for a be_vbd_create message.
- Tries to grow the vbd.
-
- @param msg: message
- @type msg: xu message
- """
val = unpackMsg('blkif_be_vbd_create_t', msg)
- d = self.send_be_vbd_grow()
- d.addCallback(self.respond_be_vbd_grow)
- return d
-
- def send_be_vbd_grow(self):
- d = defer.Deferred()
- backend = self.getBackendInterface()
- msg = packMsg('blkif_be_vbd_grow_t',
- { 'domid' : self.controller.dom,
- 'blkif_handle' : backend.handle,
- 'vdevice' : self.vdev,
- 'extent.device' : self.device,
- 'extent.sector_start' : self.start_sector,
- 'extent.sector_length' : self.nr_sectors })
- backend.writeRequest(msg, response=d)
- return d
-
- def respond_be_vbd_grow(self, msg):
- """Response handler for a be_vbd_grow message.
-
- @param msg: message
- @type msg: xu message
- """
- val = unpackMsg('blkif_be_vbd_grow_t', msg)
status = val['status']
if status != BLKIF_BE_STATUS_OKAY:
- raise XendError("Adding extent to vbd failed: device %s, error %d"
+ raise XendError("Creating vbd failed: device %s, error %d"
% (sxp.to_string(self.config), status))
return self
CMSG_BLKIF_BE_DISCONNECT = 3
CMSG_BLKIF_BE_VBD_CREATE = 4
CMSG_BLKIF_BE_VBD_DESTROY = 5
-CMSG_BLKIF_BE_VBD_GROW = 6
-CMSG_BLKIF_BE_VBD_SHRINK = 7
CMSG_BLKIF_BE_DRIVER_STATUS = 32
BLKIF_DRIVER_STATUS_DOWN = 0
BLKIF_BE_STATUS_VBD_EXISTS = 5
BLKIF_BE_STATUS_VBD_NOT_FOUND = 6
BLKIF_BE_STATUS_OUT_OF_MEMORY = 7
-BLKIF_BE_STATUS_EXTENT_NOT_FOUND = 8
+BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND = 8
BLKIF_BE_STATUS_MAPPING_ERROR = 9
blkif_formats = {
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_CREATE),
# Create a vbd device.
- 'blkif_be_vbd_grow_t':
- (CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_GROW),
- # Change the size of a vbd device. Remove?
- # Do in one go in blkif_be_vbd_create_t.
-
'blkif_be_vbd_destroy_t':
(CMSG_BLKIF_BE, CMSG_BLKIF_BE_VBD_DESTROY),
# Destroy a vbd.
debug_begin("BLKIF_BE", "VBD_CREATE");
debug_field(load, domid, "%u");
debug_field(load, blkif_handle, "%u");
+ debug_field(load, pdevice, "%u");
debug_field(load, vdevice, "%u");
debug_field(load, readonly, "%u");
debug_field(load, status, "%u");
debug_field(load, vdevice, "%u");
debug_field(load, status, "%u");
debug_end("BLKIF_BE", "VBD_DESTROY");
- } else if (msg->subtype == CMSG_BLKIF_BE_VBD_GROW) {
- blkif_be_vbd_grow_t *load;
- load = (blkif_be_vbd_grow_t *)msg->msg;
- debug_begin("BLKIF_BE", "VBD_GROW");
- debug_field(load, domid, "%u");
- debug_field(load, blkif_handle, "%u");
- debug_field(load, extent.sector_start, "%llu");
- debug_field(load, extent.sector_length, "%llu");
- debug_field(load, extent.device, "%u");
- debug_field(load, vdevice, "%u");
- debug_field(load, status, "%u");
- debug_end("BLKIF_BE", "VBD_GROW");
- } else if (msg->subtype == CMSG_BLKIF_BE_VBD_SHRINK) {
- blkif_be_vbd_shrink_t *load;
- load = (blkif_be_vbd_shrink_t *)msg->msg;
- debug_begin("BLKIF_BE", "VBD_SHRINK");
- debug_field(load, domid, "%u");
- debug_field(load, blkif_handle, "%u");
- debug_field(load, vdevice, "%u");
- debug_field(load, status, "%u");
- debug_end("BLKIF_BE", "VBD_SHRINK");
} else if (msg->subtype == CMSG_BLKIF_BE_DRIVER_STATUS) {
blkif_be_driver_status_t *load;
load = (blkif_be_driver_status_t *)msg->msg;
#define CMSG_BLKIF_BE_DISCONNECT 3 /* Disconnect i/f from remote driver. */
#define CMSG_BLKIF_BE_VBD_CREATE 4 /* Create a new VBD for an interface. */
#define CMSG_BLKIF_BE_VBD_DESTROY 5 /* Delete a VBD from an interface. */
-#define CMSG_BLKIF_BE_VBD_GROW 6 /* Append an extent to a given VBD. */
-#define CMSG_BLKIF_BE_VBD_SHRINK 7 /* Remove last extent from a given VBD. */
/* Messages to domain controller. */
#define CMSG_BLKIF_BE_DRIVER_STATUS 32
* Message request/response definitions for block-device messages.
*/
-typedef struct {
- blkif_sector_t sector_start; /* 0 */
- blkif_sector_t sector_length; /* 8 */
- blkif_pdev_t device; /* 16 */
-} PACKED blkif_extent_t; /* 20 bytes */
-
/* Non-specific 'okay' return. */
#define BLKIF_BE_STATUS_OKAY 0
/* Non-specific 'error' return. */
#define BLKIF_BE_STATUS_VBD_EXISTS 5
#define BLKIF_BE_STATUS_VBD_NOT_FOUND 6
#define BLKIF_BE_STATUS_OUT_OF_MEMORY 7
-#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND 8
+#define BLKIF_BE_STATUS_PHYSDEV_NOT_FOUND 8
#define BLKIF_BE_STATUS_MAPPING_ERROR 9
/* This macro can be used to create an array of descriptive error strings. */
domid_t domid; /* 0: Identify blkdev interface. */
u16 __pad;
u32 blkif_handle; /* 4: ...ditto... */
- blkif_vdev_t vdevice; /* 8: Interface-specific id for this VBD. */
- u16 readonly; /* 10: Non-zero -> VBD isn't writable. */
+ blkif_pdev_t pdevice; /* 8 */
+ blkif_vdev_t vdevice; /* 12: Interface-specific id for this VBD. */
+ u16 readonly; /* 14: Non-zero -> VBD isn't writable. */
/* OUT */
- u32 status; /* 12 */
-} PACKED blkif_be_vbd_create_t; /* 16 bytes */
+ u32 status; /* 16 */
+} PACKED blkif_be_vbd_create_t; /* 20 bytes */
/* CMSG_BLKIF_BE_VBD_DESTROY */
typedef struct {
u32 status; /* 12 */
} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
-/* CMSG_BLKIF_BE_VBD_GROW */
-typedef struct {
- /* IN */
- domid_t domid; /* 0: Identify blkdev interface. */
- u16 __pad0; /* 2 */
- u32 blkif_handle; /* 4: ...ditto... */
- blkif_extent_t extent; /* 8: Physical extent to append to VBD. */
- blkif_vdev_t vdevice; /* 28: Interface-specific id of the VBD. */
- u16 __pad1; /* 30 */
- /* OUT */
- u32 status; /* 32 */
-} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
-
-/* CMSG_BLKIF_BE_VBD_SHRINK */
-typedef struct {
- /* IN */
- domid_t domid; /* 0: Identify blkdev interface. */
- u16 __pad0; /* 2 */
- u32 blkif_handle; /* 4: ...ditto... */
- blkif_vdev_t vdevice; /* 8: Interface-specific id of the VBD. */
- u16 __pad1; /* 10 */
- /* OUT */
- u32 status; /* 12 */
-} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
-
/*
* CMSG_BLKIF_BE_DRIVER_STATUS:
* Notify the domain controller that the back-end driver is DOWN or UP.